<template>
  <div class="app-container">
    <el-switch
      style="margin-bottom: 10px; margin-top: 10px"
      v-model="draggable"
      active-text="开启拖拽"
      inactive-text="关闭拖拽"
      @change="getList">
    </el-switch>
    <el-button v-if="draggable" type="primary" @click="batchSave" style="margin-left: 20px">批量保存</el-button>
    <el-button type="danger" @click="batchDelete" style="margin-left: 20px">批量删除</el-button>
    <el-tree
      v-loading="treeLoading"
      :data="list"
      :props="defaultProps"
      :expand-on-click-node="false"
      show-checkbox
      node-key="catId"
      :default-expanded-keys="expandedKey"
      :draggable="draggable"
      :allow-drop="allowDrop"
      @node-drop="handleDrop"
      ref="menuTree"
    >
      <span class="custom-tree-node" style="width: 100%" slot-scope="{ node, data }">
        <span style="line-height: 28px">{{ node.label }}</span>
        <span style="float: right">
          <el-button
            style="margin-right: 20px;"
            v-if="node.level < 3"
            type="primary"
            size="mini"
            @click="() => append(data)">
            添加
          </el-button>
          <el-button
            style="margin-right: 20px;"
            type="success"
            size="mini"
            @click="() => update(data)">
            修改
          </el-button>
          <el-button
            slot="reference"
            style="margin-right: 20px;"
            v-if="node.childNodes.length === 0"
            type="danger"
            size="mini"
            @click="() => remove(node, data)">
            删除
          </el-button>
        </span>
      </span>
    </el-tree>

    <el-dialog
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      width="30%"
      :close-on-click-modal="false">
      <el-form ref="category" :model="category" :rules="categoryRules">
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="category.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="图标" prop="icon">
          <el-input v-model="category.icon" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="计量单位" prop="productUnit">
          <el-input v-model="category.productUnit" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitData">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>

import { list, delMultiple, updateSort, add, update } from "../../../api/goods/category";

export default {
  data() {
    const validateName = (rule, value, callback) => {
      if (value.length < 1 || value.length > 10) {
        callback(new Error('描述不得小于 1 个或者大于 10 个字符'))
      } else {
        callback()
      }
    }
    return {
      list: [],
      expandedKey: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      category: {
        catId: '',
        name: '',
        parentCid: 0,
        catLevel: 0,
        sort: 0,
        icon: '',
        productUnit: ''
      },
      categoryRules: {
        name: [{ required: true, trigger: 'blur', validator: validateName }]
      },
      updateNodes: [],
      expandedKeyList: [],
      draggable: false,
      dialogVisible: false,
      dialogType: '',
      dialogTitle: '',
      maxLevel: 0,
      treeLoading: false,
    }
  },
  created() {
    this.getList()
  },
  methods: {
    batchDelete() {
      const checkedKeys = this.$refs.menuTree.getCheckedKeys()
      const checkedNodes = this.$refs.menuTree.getCheckedNodes()
      const name = checkedNodes.map(item => { return ' 【' + item.name + '】 ' })
      if (checkedKeys.length === 0) {
        this.$message({
          message: '请选择要删除的菜单',
          type: 'info'
        })
      } else {
        this.$confirm(`此操作将删除 ${name} 菜单, 是否继续?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          delMultiple(checkedKeys)
            .then(() => {
              this.$message({
                message: '删除成功',
                type: 'success'
              })
              this.getList()
            })
        }).catch(() => {})
      }
    },
    batchSave() {
      updateSort(this.updateNodes)
        .then(() => {
          this.$message({
            message: '菜单顺序修改成功',
            type: 'success'
          })
          this.getList()
          this.updateNodes = []
          this.expandedKey = this.expandedKeyList
        })
    },
    allowDrop(draggingNode, dropNode, type) {
      this.maxLevel = draggingNode.level
      this.countNodeLevel(draggingNode)
      const a = this.maxLevel - draggingNode.level
      if (type === 'inner') {
        if ((dropNode.level + a + 1) > 3) {
          return false
        }
      } else {
        if ((dropNode.level + a) > 3) {
          return false
        }
      }
      return true
    },
    handleDrop(draggingNode, dropNode, dropType, ev) {
      // draggingNode 当前拖拽的对象
      // dropNode 拖拽到的目标对象

      let pCid = 0
      let siblings = []
      let catLevel = 0
      if (dropType === 'before' || dropType === 'after') {
        pCid = dropNode.parent.data.catId || 0
        siblings = dropNode.parent.childNodes
        catLevel = dropNode.level
      } else {
        pCid = dropNode.data.catId
        siblings = dropNode.childNodes
        catLevel = dropNode.level + 1
      }

      for (let i = 0; i < siblings.length; i++) {
        const id = siblings[i].data.catId
        if (id === draggingNode.data.catId) {
          if (catLevel !== draggingNode.level) {
            this.updateNodes.push({ catId: id, sort: i, parentCid: pCid, catLevel: catLevel })
            draggingNode.childNodes.forEach(item => {
              this.updateNodes.push({ catId: item.data.catId, catLevel: catLevel + 1 })
            })
          } else {
            this.updateNodes.push({ catId: id, sort: i, parentCid: pCid })
          }
        } else {
          this.updateNodes.push({ catId: id, sort: i })
        }
      }
      this.expandedKeyList.push(pCid)
    },
    countNodeLevel(node) {
      node.childNodes.forEach(item => {
        if (item.level > this.maxLevel) {
          this.maxLevel = item.level
        }
        this.countNodeLevel(item)
      })
    },
    getList() {
      this.treeLoading = true
      list()
        .then(request => {
          this.list = request.data
          this.treeLoading = false
        })
    },
    append(data) {
      this.dialogVisible = true
      this.category.name = ''
      this.category.catId = ''
      this.category.icon = ''
      this.category.productUnit = ''
      this.category.parentCid = data.catId
      this.category.catLevel = data.catLevel * 1 + 1
      this.dialogType = 'add'
      this.dialogTitle = '添加菜单'
    },
    update(data) {
      this.dialogVisible = true
      this.category.name = data.name
      this.category.catId = data.catId
      this.category.icon = data.icon
      this.category.productUnit = data.productUnit
      this.category.parentCid = data.parentCid
      this.dialogType = 'update'
      this.dialogTitle = '修改菜单'
    },
    remove(node, data) {
      this.$confirm(`此操作将永久删除【${data.name}】菜单, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delMultiple([data.catId])
          .then(() => {
            this.$message({
              message: '删除成功',
              type: 'success'
            })
            this.getList()
            this.expandedKey = [node.parent.data.catId]
          })
      }).catch(() => {})
    },
    submitData() {
      if (this.dialogType === 'add') {
        this.addCategory()
      } else {
        this.updateCategory()
      }
    },
    addCategory() {
      this.$refs.category.validate((valid, obj) => {
        if (valid) {
          add(this.category)
            .then(() => {
              this.$message({
                message: '添加成功',
                type: 'success'
              })
              this.getList()
              this.dialogVisible = false
              this.expandedKey = [this.category.parentCid]
            })
        }
      })
    },
    updateCategory() {
      this.$refs.category.validate((valid, obj) => {
        if (valid) {
          const { catId, name, icon, productUnit } = this.category
          update({ catId, name, icon, productUnit })
            .then(() => {
              this.$message({
                message: '修改成功',
                type: 'success'
              })
              this.getList()
              this.dialogVisible = false
              this.expandedKey = [this.category.parentCid]
            })
        }
      })
    }
  }
}
</script>

<style lang="scss">
.el-tree-node__content {
  height: 40px;
}
</style>

